# 1. 加载必要的包
library(mice)
library(dplyr)
library(tidyr)

# 2. 查看原始数据基本情况
cat("\n原始数据维度:", dim(qwe), "\n")
cat("缺失值数量:", sum(is.na(qwe)), "\n")
cat("缺失值比例:", round(mean(is.na(qwe)) * 100, 2), "%\n")

str(qwe)
summary(qwe)

# 3. 转换变量类型
qwe$id <- as.factor(qwe$id)
qwe$time <- as.factor(qwe$time)
numeric_cols <- c("s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11")
qwe[numeric_cols] <- lapply(qwe[numeric_cols], as.numeric)

# 4. 多重插补（mice）
init <- mice(qwe, maxit = 0)          # 只初始化，不插补
meth <- init$method
pred <- init$predictorMatrix

# 对 s1~s11 使用 PMM 方法
meth[numeric_cols] <- "pmm"
# 不允许 id 和 time 作为预测变量（即不用于预测其他变量）
pred[, c("id", "time")] <- 0

# 执行插补，生成5个完整数据集
imp <- mice(qwe, 
            m = 5, 
            maxit = 10, 
            method = meth,
            predictorMatrix = pred,
            seed = 123,
            print = TRUE)

summary(imp)

# 提取第一个插补后的完整数据集（也可选其他，如 complete(imp, 'long')）
qwe_complete <- complete(imp, 1)

# 5. 为转换宽格式做准备：将 time 转为数值
qwe_complete <- qwe_complete %>%
  arrange(id, time) %>%
  mutate(time_num = case_when(
    time == "T0" ~ 0,
    time == "T1" ~ 1,
    time == "T2" ~ 2,
    time == "T3" ~ 3,
    time == "T4" ~ 4,
    TRUE ~ NA_real_
  ))

# 6. 转换为宽格式：每个 id 一行，不同时间点的 s1~s11 作为不同列
qwe_wide <- qwe_complete %>%
  select(id, time_num, all_of(numeric_cols)) %>%
  pivot_wider(
    id_cols = id,
    names_from = time_num,
    values_from = all_of(numeric_cols),
    names_glue = "T{time_num}_{.value}"   # 生成列名如 T0_s1, T0_s2, ..., T1_s1, ...
  )

# 7. 查看结果
cat("\n宽格式数据维度：\n")
dim(qwe_wide)
head(qwe_wide)

# 保存为 CSV（长格式）
write.csv(complete(imp, "long"), "mice_imputed_long.csv", row.names = FALSE)

# 保存为 Excel 的多个工作表（需 openxlsx 包）
library(openxlsx)
wb <- createWorkbook()
for (i in 1:imp$m) {
  addWorksheet(wb, paste0("imp_", i))
  writeData(wb, i, complete(imp, i))
}
saveWorkbook(wb, "mice_imputed.xlsx", overwrite = TRUE)

# 保存到桌面
desktop_path <- file.path(Sys.getenv("USERPROFILE"), "Desktop")
csv_temp <- file.path(desktop_path, "mice_imputed_long.csv")
write.csv(complete(imp, "long"), csv_temp, row.names = FALSE)